package site.xuqing.autohelperengine;

import android.os.Looper;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

import site.xuqing.autohelper.bean.StepBean;
import site.xuqing.autohelper.bean.StepCallbackBean;
import site.xuqing.autohelper.bean.StepContainerBean;
import site.xuqing.autohelper.listener.OnStepListener;
import site.xuqing.autohelper.type.StepType;
import site.xuqing.autohelperengine.constant.Constant;
import site.xuqing.autohelperengine.local.bean.StepLocalBean;
import site.xuqing.autohelperengine.local.bean.StepLocalSaveBean;
import site.xuqing.autohelperengine.local.bean.StepLocalAddType;
import site.xuqing.autohelperengine.local.overlay.FloatViewManager;
import site.xuqing.autohelperengine.service.HelperService;
import site.xuqing.autohelperengine.local.util.StepSaveUtil;
import site.xuqing.autohelperengine.util.StepExecutorImpl;
import site.xuqing.autohelper.util.StringUtil;

/**
 * @author xuqing
 */
public class StepManager {
    /**
     * 当前步骤循环状态，0：无循环，1：循环开始，2：循环结束（有循环）
     */
    public static int currentStepLoopState = 0;
    private static HelperService service;
    private static boolean isRunning = false;
    private static int stepIndex = 0;
    private static int loopStartIndex = 0;
    private static int loopExecutedTimes = 0;
    private static boolean loopFinish = false;
    private static final List<StepLocalBean> stepLocalBeans = new ArrayList<>();
    private static StepContainerBean stepContainerBean;
    private static StepLocalSaveBean stepLocalSaveBean;
    private static final List<StepBean> stepBeans = new ArrayList<>();
    private static final StepExecutorImpl stepUtil = new StepExecutorImpl();
    private static Thread thread;
    private static String currentScreenActivityClassName;
    private static String currentNodeActivityClassName;
    private static final Object LOCK = new Object();
    private static OnStepListener onStepListener;
    
    public static void setService(HelperService service) {
        StepManager.service = service;
    }
    
    public static HelperService getService() {
        return StepManager.service;
    }
    
    public static void setCurrentScreenActivityClassName(String currentScreenActivityClassName) {
        //只有当是非本地步骤时才需要判断锁
        if (stepBeans.size() > 0) {
            synchronized(LOCK) {
                StepManager.currentScreenActivityClassName = currentScreenActivityClassName;
                if (currentScreenActivityClassName.equals(currentNodeActivityClassName)) {
                    System.out.println("lock:触发了一次解锁");
                    LOCK.notifyAll();
                }
            }
            //把currentScreenActivityClassName发送给自定义消息
            if (stepIndex < stepBeans.size() && stepBeans.get(stepIndex).getStepScript() != null) {
                stepBeans.get(stepIndex).getStepScript().unlock(currentScreenActivityClassName);
            }
        }
    }
    
    public static String getCurrentScreenActivityClassName() {
        return currentScreenActivityClassName;
    }
    
    /**
     * 保存步骤
     *
     * @param stepBean StepLocalBean
     */
    public static void setLocalStep(StepLocalBean stepBean) {
        StepManager.stepLocalBeans.add(stepBean);
    }
    
    /**
     * 从外部加载已保存的步骤集合
     *
     * @param stepLocalSaveBean StepLocalSaveBean
     */
    public static void setLocalSteps(StepLocalSaveBean stepLocalSaveBean) {
        reset();
        StepManager.stepLocalSaveBean = stepLocalSaveBean;
        StepManager.stepLocalBeans.addAll(stepLocalSaveBean.getStepBeans());
    }
    
    public static void setSteps(StepContainerBean stepContainerBean, OnStepListener onStepListener) {
        reset();
        StepManager.stepContainerBean = stepContainerBean;
        StepManager.stepBeans.addAll(stepContainerBean.getStepBeans());
        StepManager.onStepListener = onStepListener;
    }
    
    /**
     * 保存设计好的步骤集合
     */
    public static boolean saveLocalSteps(String name) {
        if (!stepLocalBeans.isEmpty()) {
            return StepSaveUtil.saveLocalSteps(stepLocalBeans, name);
        }
        return false;
    }
    
    public static boolean saveSteps() {
        if (stepContainerBean != null) {
            return StepSaveUtil.saveSteps(stepContainerBean);
        }
        return false;
    }
    
    /**
     * 重新开始
     */
    public static void reset() {
        stepLocalBeans.clear();
        stepLocalSaveBean = null;
        stepContainerBean = null;
        stepBeans.clear();
        currentScreenActivityClassName = null;
        currentNodeActivityClassName = null;
        synchronized(LOCK) {
            LOCK.notifyAll();
        }
        isRunning = false;
    }
    
    public static void executeStart() {
        if (thread != null) {
            executeStop();
            thread = null;
        }
        isRunning = true;
        if (onStepListener != null) {
            try {
                StepCallbackBean stepCallbackBean = new StepCallbackBean();
                stepCallbackBean.setErrorCode(0);
                if (stepContainerBean != null && stepContainerBean.getName() != null) {
                    stepCallbackBean.setMessage(stepContainerBean.getName());
                }
                onStepListener.onStart(stepCallbackBean);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        thread = new Thread() {
            @Override
            public void run() {
                try {
                    while (isRunning) {
                        if (stepLocalBeans.size() > 0) {
                            System.out.println("local step");
                            StepLocalBean stepLocalBean = stepLocalBeans.get(stepIndex);
                            if (stepLocalBean.isLoopStart()) {
                                loopStartIndex = stepIndex;
                                if (stepLocalBean.getLoopTimes() > 0) {
                                    if (loopExecutedTimes < stepLocalBean.getLoopTimes() - 1) {
                                        loopExecutedTimes++;
                                    } else {
                                        loopFinish = true;
                                    }
                                }
                            }
                            System.out.println("休眠" + stepLocalBean.getTaskTime() + "毫秒开始");
                            sleep(stepLocalBean.getTaskTime());
                            System.out.println("休眠" + stepLocalBean.getTaskTime() + "毫秒完成");
                            if (!isRunning) {
                                break;
                            }
                            Step.step(service, stepLocalBean, stepUtil);
                            stepIndex++;
                            if (stepIndex == stepLocalBeans.size() && (!stepLocalBean.isLoopEnd() || loopFinish)) {
                                if (Looper.myLooper() == null) {
                                    Looper.prepare();
                                }
                                if (stepLocalSaveBean != null && stepLocalSaveBean.getStepLocalType() == StepLocalAddType.INSET) {
                                    Toast.makeText(service, "执行完成", Toast.LENGTH_SHORT).show();
                                    AutoHelper.getInstance().startApp(service, service.getPackageName());
                                    FloatViewManager.getInstance().hideMenuView();
                                } else {
                                    FloatViewManager.getInstance().showCreateMenuView(null);
                                    FloatViewManager.getInstance().hideCoverView();
                                    FloatViewManager.getInstance().showMessageView("自定义步骤执行完成");
                                }
                                Looper.loop();
                                executeStop();
                            }
                            if (stepLocalBean.isLoopEnd() && !loopFinish) {
                                stepIndex = loopStartIndex;
                            } else {
                                loopExecutedTimes = 0;
                                loopFinish = false;
                            }
                        } else if (stepBeans.size() > 0) {
                            System.out.println(" step");
                            StepBean stepBean = stepBeans.get(stepIndex);
                            if (stepBean.isLoopStart()) {
                                loopStartIndex = stepIndex;
                                if (stepBean.getLoopTimes() > 0) {
                                    if (loopExecutedTimes < stepBean.getLoopTimes() - 1) {
                                        loopExecutedTimes++;
                                    } else {
                                        loopFinish = true;
                                    }
                                }
                            }
                            System.out.println("休眠" + stepBean.getTaskTime() + "毫秒开始");
                            sleep(stepBean.getTaskTime());
                            System.out.println("休眠" + stepBean.getTaskTime() + "毫秒完成");
                            if (!isRunning) {
                                break;
                            }
                            Step.step(service, stepBean, stepUtil, onStepListener);
                            //判断是否已到达所需要操作的界面，如果还没到达就等待，如果已到达就继续运行
                            if (stepBean.getStepType() != StepType.CUSTOM && !StringUtil.isEmptyString(stepBean.getCurrentScreenActivityClassName()) && !stepBean.getCurrentScreenActivityClassName().equals(getCurrentScreenActivityClassName())) {
                                synchronized(LOCK) {
                                    currentNodeActivityClassName = stepBean.getCurrentScreenActivityClassName();
                                    System.out.println("current Node className:" + currentNodeActivityClassName);
                                    System.out.println("current Screen className:" + getCurrentScreenActivityClassName());
                                    System.out.println("lock:触发了一次锁");
                                    LOCK.wait();
                                }
                            }
                            stepIndex++;
                            if (stepIndex == stepBeans.size() && (!stepBean.isLoopEnd() || loopFinish)) {
                                System.out.println("自定义任务执行完成");
                                if (Looper.myLooper() == null) {
                                    Looper.prepare();
                                }
                                if (onStepListener != null) {
                                    StepCallbackBean stepCallbackBean = new StepCallbackBean();
                                    stepCallbackBean.setErrorCode(0);
                                    if (stepContainerBean != null && stepContainerBean.getName() != null) {
                                        stepCallbackBean.setMessage(stepContainerBean.getName());
                                    }
                                    onStepListener.onStepScriptExecuteFinish(stepCallbackBean);
                                }
                                Looper.loop();
                                executeStop();
                                executeClear();
                            }
                            if (stepBean.isLoopEnd() && !loopFinish) {
                                stepIndex = loopStartIndex;
                            } else {
                                loopExecutedTimes = 0;
                                loopFinish = false;
                            }
                        } else {
                            if (Looper.myLooper() == null) {
                                Looper.prepare();
                            }
                            if (stepLocalBeans.size() > 0) {
                                FloatViewManager.getInstance().showCreateMenuView(null);
                                FloatViewManager.getInstance().hideCoverView();
                            }
                            FloatViewManager.getInstance().showMessageView("无步骤可执行");
                            
                            if (onStepListener != null) {
                                StepCallbackBean stepCallbackBean = new StepCallbackBean();
                                stepCallbackBean.setErrorCode(0);
                                if (stepContainerBean != null && stepContainerBean.getName() != null) {
                                    stepCallbackBean.setMessage(stepContainerBean.getName());
                                }
                                onStepListener.onStepScriptExecuteFinish(stepCallbackBean);
                            }
                            Looper.loop();
                            executeStop();
                        }
                    }
                } catch (final Exception e) {
                    e.printStackTrace();
                    if (Looper.myLooper() == null) {
                        Looper.prepare();
                    }
                    if (stepLocalBeans.size() > 0) {
                        FloatViewManager.getInstance().showCreateMenuView(null);
                        FloatViewManager.getInstance().hideCoverView();
                    }
                    
                    if (Constant.SHOW_MSG) {
                        FloatViewManager.getInstance().showMessageView("执行出错：" + e.getMessage());
                    }
                    
                    if (onStepListener != null) {
                        try {
                            onStepListener.onError(null);
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                    Looper.loop();
                    executeStop();
                    executeClear();
                }
            }
        };
        thread.start();
    }
    
    public static void executeStop() {
        isRunning = false;
        stepIndex = 0;
        loopStartIndex = 0;
        loopExecutedTimes = 0;
        loopFinish = false;
        currentNodeActivityClassName = null;
        currentScreenActivityClassName = null;
        synchronized(LOCK) {
            LOCK.notifyAll();
        }
    }
    
    public static void executeClear() {
        stepLocalBeans.clear();
        stepLocalSaveBean = null;
        stepContainerBean = null;
        stepBeans.clear();
    }
}
